package com.thread;

import com.bean.DocDossierFileCatalog;
import com.bean.DossierFileCatalog;
import com.config.Config;
import com.config.Configuration;
import com.listener.ProgressListener;
import com.util.ConfigUtil;
import com.util.DBUtil;

import java.util.*;

/**
 * 线程任务分发
 *
 * @author Smile
 */
public class Distribute {
    private static final Config config = ConfigUtil.getConfig();
    private static final Configuration configuration = config.getCtfz();

    private static final int Thread_Size = configuration.getThreadSize();


    /**
     * 分发任务
     *
     * @param dossierFile
     * @param docDossierFile
     * @return
     */
    public static Map<String, Object> distributeTask(List<DossierFileCatalog> dossierFile, List<DocDossierFileCatalog> docDossierFile) {

        List<List<DossierFileCatalog>> dossierTask = new ArrayList<>();
        List<List<DocDossierFileCatalog>> docDossierTask = new ArrayList<>();

        // 剩余数量
        int dossierSurplus = dossierFile.size() % Thread_Size;
        int docDossierSurplus = docDossierFile.size() % Thread_Size;

        int dossierCount = (int) Math.ceil(dossierFile.size() / Thread_Size);
        int docdossierCount = (int) Math.ceil(docDossierFile.size() / Thread_Size);

        int start = 0, end = dossierCount;
        for (int i = 0; i < Thread_Size; i++) {
            if (dossierSurplus > 0) {
                end++;
                dossierSurplus--;
            }
            if (start == end) {
                break;
            }
            end = end > dossierFile.size() ? dossierFile.size() : end;
            dossierTask.add(dossierFile.subList(start, end));
            start = end;
            end = end + dossierCount;
        }

        start = 0;
        end = docdossierCount;
        for (int i = 0; i < Thread_Size; i++) {

            if (docDossierSurplus > 0) {
                end++;
                docDossierSurplus--;
            }
            if (start == end) {
                break;
            }

            end = end > docDossierFile.size() ? docDossierFile.size() : end;
            docDossierTask.add(docDossierFile.subList(start, end));
            start = end;
            end = end + docdossierCount;
        }
        Map<String, Object> res = new HashMap<>();
        res.put("dossier", dossierTask);
        res.put("docDossier", docDossierTask);

        return res;
    }

    public static boolean distributeAndRun(DBUtil dbUtil, List<DossierFileCatalog> dossierFile, List<DocDossierFileCatalog> docDossierFile, ProgressListener listener) throws InterruptedException {
        Map<String, Object> tasks = distributeTask(dossierFile, docDossierFile);
        List<List<DossierFileCatalog>> dossierTask = (List<List<DossierFileCatalog>>) tasks.get("dossier");
        List<List<DocDossierFileCatalog>> docDossierTask = (List<List<DocDossierFileCatalog>>) tasks.get("docDossier");

        Vector<Thread> threadVector = new Vector<>();

        FileDownloadThread downloadThread = null;
        for (int i = 0; i < Thread_Size; i++) {
            if (i >= dossierTask.size() && i >= docDossierTask.size()) {
                break;
            }
            downloadThread = new FileDownloadThread("download" + i, dbUtil, listener);
            if (i < dossierTask.size()) {
                downloadThread.setDossierList(dossierTask.get(i));
            }
            if (i < docDossierTask.size()) {
                downloadThread.setDocDossierList(docDossierTask.get(i));
            }
            Thread thread = new Thread(downloadThread);
            threadVector.add(thread);
            thread.start();
        }

        for (Thread thread : threadVector) {
            thread.join();
        }
        ProgressListener.Progress progress = new ProgressListener.Progress();
        progress.setID("DownloadFileFinished");
        listener.progress(progress);
        System.out.println("执行完成");
        return true;
    }
}
